package de.fhin.mas.agents.searcher.behaviours;

import jade.domain.FIPANames;
import jade.domain.FIPAAgentManagement.FailureException;
import jade.domain.FIPAAgentManagement.NotUnderstoodException;
import jade.domain.FIPAAgentManagement.RefuseException;
import jade.lang.acl.ACLMessage;
import jade.proto.ContractNetResponder;
import de.fhin.mas.MASEvents;
import de.fhin.mas.agents.searcher.SearcherAgent;
import de.fhin.mas.ontology.SearchableObject;
import de.fhin.mas.util.MessageUtil;

/**
 * Dieses <tt>Behaviour</tt> behandelt alle eingehenden neuen Suchaufträge
 * ("new_order" CFPs) gemaess dem ContractNet Protokoll.
 * 
 * @author Thomas Schläfer
 */
public class NewOrderContractNetResponder extends ContractNetResponder {

	/**
	 * Die eindeutige ID zur Serialisierung ueber das Netzwerk.
	 */
	private static final long serialVersionUID = -7009349224599434385L;

	/**
	 * Erzeugt eine neue <tt>NewOrderContractNetResponder<tt> Instanz.
	 * 
	 * @param parentAgent
	 *            Der Sucher-Dummy-Agent, zu dem das Behaviour gehoeren soll.
	 */
	public NewOrderContractNetResponder(SearcherAgent parentAgent) {
		super(parentAgent, MessageUtil.buildBasicCommunicationTemplate(
				FIPANames.InteractionProtocol.FIPA_CONTRACT_NET,
				MASEvents.NEW_ORDER.getName(), ACLMessage.CFP, null));
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected ACLMessage handleCfp(ACLMessage cfp) throws RefuseException,
			FailureException, NotUnderstoodException {

		// Wir nehmen den neuen Suchauftrag immer an -> mit PROPOSE antworten
		ACLMessage propose = cfp.createReply();
		propose.setPerformative(ACLMessage.PROPOSE);
		return propose;
	}

	/**
	 * Diese Methode behandelt ein eigehendes Accept-Proposal, Startet die
	 * Suchen und informiert den Auftraggeber.
	 */
	@Override
	protected ACLMessage handleAcceptProposal(ACLMessage cfp,
			ACLMessage propose, ACLMessage accept) throws FailureException {

		SearcherAgent searcherAgent = (SearcherAgent) myAgent;
		ACLMessage result = accept.createReply();

		SearchableObject searchObject = null;

		// Auftrag wurde bestätigt, Suchen starten
		searchObject = searcherAgent.extractSearchableObjectFromMsg(cfp);
		if (searchObject != null) {
			// Zielsuche starten, mit dem zu suchenden Objekt als Parameter
			searcherAgent.startTargetSearch(searchObject);
			result.setPerformative(ACLMessage.INFORM);

		} else {
			result.setPerformative(ACLMessage.FAILURE);
		}

		// INFORM / FAILURE zurücksenden
		return result;
	}

}
